package com.iflytek.uoamp.agent.monitor.find.imp.baseitem;

import com.alibaba.fastjson.JSON;
import com.iflytek.uoamp.agent.common.constants.CommonConstants;
import com.iflytek.uoamp.agent.core.sender.monitorsender.responseObj.Program;
import com.iflytek.uoamp.agent.core.sender.monitorsender.responseObj.ProgramType;
import com.iflytek.uoamp.agent.monitor.find.CMDExextor;
import com.iflytek.uoamp.agent.monitor.find.CMDExextor.ShellResult;
import com.iflytek.uoamp.agent.monitor.find.obj.NetWork;
import com.iflytek.uoamp.agent.monitor.mcagent.MCAgentConfig;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.hyperic.sigar.*;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author gaowei 自动发现基础类;用于查找所有服务器的信息;默认开启;
 */
public class FindLinuxBaseMonitorItem extends FindBaseMonitorItemAbs {
	public static DecimalFormat df = new DecimalFormat("######0.00");

	/**
	 * 获取所有的本地挂载点
	 * */
	@Override
	protected List<Program> getDisks() {
		ShellResult result = CMDExextor.execut("df -hP");
		if (null == result || result.output == null || "".equals(result.output)) {
			return null;
		}

		List<Program> list = new LinkedList<Program>();
		String[] lines = result.output.split("\n");
		for (int i = 1; i < lines.length; i++) {
			List<String> flags = new LinkedList<String>();
			Program cprogram = new Program();
			String[] path = lines[i].split("\\s+");
			String pathflag = null;
			// 根目录重命名为 root
			if ("/".equals(path[path.length - 1])) {
				pathflag = "root";
			} else {
				int index = path[path.length - 1].lastIndexOf("/");
				pathflag = path[path.length - 1].substring(index + 1);
			}
	
			cprogram.setCpname("disk_" + pathflag);
			cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
			cprogram.setType(ProgramType.BASE);
			cprogram.setFlags(flags);
			cprogram.setPath(pathflag);
			list.add(cprogram);

		}
		return list;
	}

	/**
	 * 获取所有的本地挂载点
	 * */
	@Override
	protected List<Program> getDiskIO() {
		ShellResult result = null;
		String findDiskIOCmd = "iostat -x 1 1";
		try {
			result = CMDExextor.execut(findDiskIOCmd);
		} catch (Exception e) {
			Logger.getRootLogger().error(findDiskIOCmd + " catch exception ", e);
		}
		if (result == null || result.output == null || "".equals(result.output)) {
			Logger.getRootLogger().info("execute cmd <".concat(findDiskIOCmd) + "> result is null.");
			return null;
		}

		List<Program> list = new LinkedList<Program>();
		String[] lines = result.output.split("\n");
		boolean isStart = false;
		for (int i = 0; i < lines.length; i++) {
			if (lines[i].contains("Device:")) {
				isStart = true;
				continue;
			}

			if (!isStart) {
				continue;
			}

			String[] path = lines[i].split("\\s+");
			Program ioprogram = new Program();
			ioprogram.setCpname("diskio");
			ioprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
			ioprogram.setType(ProgramType.BASE);
			List<String> flags = new LinkedList<String>();
			flags.add(path[0]);
			ioprogram.setFlags(flags);
			list.add(ioprogram);
		}
		return list;
	}

	/**
	 * 获取 cpu 监控项
	 * */
	@Override
	protected List<Program> getCPU() {
		ShellResult result = null;
		try {
			result = CMDExextor.execut(CommonConstants.GETCPU_PATH);
		} catch (Exception e) {
			Logger.getRootLogger().error("find cpu catch exception! " + e.toString());
		}
		if (result == null || result.output == null || "".equals(result.output)) {
			Logger.getRootLogger().info("execute cmd <".concat(CommonConstants.GETCPU_PATH) + "> result is null.");
			return null;
		}

		List<Program> list = new LinkedList<Program>();
		String[] lines = result.output.split("\n");
		for (int i = 0; i < lines.length; i++) {
			Program ioprogram = new Program();
			ioprogram.setCpname("cpu");
			ioprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
			ioprogram.setType(ProgramType.BASE);
			List<String> flags = new LinkedList<String>();
			flags.add(i + "");
			ioprogram.setFlags(flags);
			ioprogram.setPort(i);
			list.add(ioprogram);
		}
		Program cprogram = new Program();
		cprogram.setCpname("cpu");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.BASE);
		List<String> flags = new LinkedList<String>();
		flags.add("all");
		cprogram.setFlags(flags);
		cprogram.setPort(100);
		list.add(cprogram);
		return list;
	}

	/**
	 * 内存监控项
	 * */
	@Override
	protected Program getMemory() {
		Program cprogram = new Program();
		cprogram.setCpname("memory");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.BASE);
		return cprogram;
	}

	/**
	 * 本地网卡获取
	 * */
	@Override
	protected Program getInterface() {
		String ip = MCAgentConfig.getInstance().getMonitoredPointIp();
		Logger.getRootLogger().info("get network ip =======================================> " + ip);

		if (ip == null || ip.isEmpty()) {
			return null;
		}

		Sigar sigar = new Sigar();
		LinkedList<NetWork> network = new LinkedList<NetWork>();
		// 获取网络流量等信息
		try {
			Logger.getRootLogger().info("start getNetInterfaceStat.....");
			String[] ifNames = sigar.getNetInterfaceList();
			Logger.getRootLogger().info("!IFF_UP...skipping getNetInterfaceStat" + ifNames.length);
			for (int i = 0; i < ifNames.length; i++) {
				String name = ifNames[i];
				NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name);

				if ((ifconfig.getFlags() & 1L) <= 0L) {
					Logger.getRootLogger().error("!IFF_UP...skipping getNetInterfaceStat");
					continue;
				}

				NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name);

				if (ip.equals(ifconfig.getAddress())) {
					NetWork curnet = new NetWork();
					curnet.setName(name);
					curnet.setIp(ifconfig.getAddress());
					curnet.setTransportByte(ifstat.getRxBytes() + "");

					network.add(curnet);
				}
			}
		} catch (Exception e) {
			Logger.getRootLogger().error("getInterface exception ", e);
			return null;
		}

		NetWork netWork = null;
		for (NetWork cur : network) {
			// 如果没有 IP 则跳过;
			if (cur.getIp() != null && cur.getIp().equals(ip)) {
				netWork = cur;
				break;
			}
		}

		if (netWork == null)
			return null;

		Program cprogram = new Program();
		cprogram.setCpname("interface");
		cprogram.setIp(ip);
		cprogram.setType(ProgramType.BASE);
		List<String> flags = new LinkedList<String>();
		flags.add(netWork.getName());
		cprogram.setFlags(flags);
		// get主机名称
		cprogram.setHostname(MCAgentConfig.getInstance().getMonitoredHostName());
		return cprogram;
	}

	/**
	 * 初始化及其发现类;
	 * 
	 * @param path
	 *            ;是允许的 IP 头的配置文件;
	 */
	public FindLinuxBaseMonitorItem(String path) {
		super(path);
	}

	/**
	 * 获取 cpu 具体信息
	 * */
	@Override
	protected Program getCPUInfo() {
		Sigar sigar = new Sigar();
		Map<String, String> cupInfo = new HashMap<String, String>();
		try {
			CpuInfo[] cpuInfos = sigar.getCpuInfoList();
			if (cpuInfos.length > 0) {
				List<String> cpu = new ArrayList<String>();
				for (CpuInfo cpuInfo : cpuInfos) {
					String cpuMdle = cpuInfo.getModel();
					if (!cpu.contains(cpuMdle)) {
						cpu.add(cpuMdle);
					}
				}
				cupInfo.put("cpuNum", cpu.size() + "");
				cupInfo.put("Mhz", df.format((double) cpuInfos[0].getMhz() / 1024) + "");
				cupInfo.put("Cores", cpuInfos.length + "");
			}
		} catch (SigarException e) {
			Logger.getRootLogger().error("getCPUInfo fail!", e);
		}

		Program cprogram = new Program();
		cprogram.setCpname("cpuInfo");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.INFO);
		cprogram.setHeaders(cupInfo);
		return cprogram;
	}

	/**
	 * 内存监控项具体信息
	 * */
	@Override
	protected Program getMemoryInfo() {
		Sigar sigar = new Sigar();
		Map<String, String> memoryInfo = new HashMap<String, String>();
		try {
			Mem mem = sigar.getMem();
			memoryInfo.put("totalMemory", (mem.getTotal() / 1024L / 1024L / 1024L) + 1 + "");
		} catch (SigarException e) {
			Logger.getRootLogger().error("Linux getMemoryInfo fail!", e);
		}

		Program cprogram = new Program();
		cprogram.setCpname("memoryInfo");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.INFO);
		cprogram.setHeaders(memoryInfo);
		return cprogram;
	}

	/**
	 * 操作系统具体信息
	 * */
	@Override
	protected Program getOsInfo() {
		OperatingSystem operatingSystem = OperatingSystem.getInstance();
		Map<String, String> oSInfo = new HashMap<String, String>();
		oSInfo.put("systemInfo", operatingSystem.getVendor() + operatingSystem.getVendorVersion());
		Program cprogram = new Program();
		cprogram.setCpname("systemInfo");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.INFO);
		cprogram.setHeaders(oSInfo);
		return cprogram;
	}

	/**
	 * 操作系统JDK版本具体信息
	 * */

	@Override
	protected Program getJdkVersion() {
		String jdkVersion = System.getProperty("java.version");
		Map<String, String> jdkInfo = new HashMap<String, String>();
		jdkInfo.put("jdkVersion", jdkVersion);
		Program cprogram = new Program();
		cprogram.setCpname("jdkVersion");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.INFO);
		cprogram.setHeaders(jdkInfo);
		return cprogram;
	}

	/*
	 * (非 Javadoc)
	 * 
	 * 
	 * @return
	 * 
	 * @see
	 * com.iflytek.uoamp.agent.monitor.find.imp.baseitem.FindBaseMonitorItemAbs
	 * #getRunTime()
	 */

	@Override
	protected Program getRunTime() {
		ShellResult cmdResult = CMDExextor.execut(CommonConstants.GETRUNTIME_PATH);
		String outPut = cmdResult.output;
		Logger.getRootLogger().info("check_runtime result: " + outPut);
		String[] result;
		String day = "0";
		String hour = "0";
		String min = "0";
		String runTime = " ";
		try {
			if (StringUtils.isNotBlank(outPut)) {
				result = outPut.split(",");
				if (result.length == 6) {
					day = result[0].trim().split(" ")[2];
					if (result[1].split(":").length > 1) {
						hour = result[1].trim().split(":")[0];
						min = result[1].split(":")[1];
					} else {
						min = result[1].trim().split(" ")[0];
					}
				} else if (result.length == 5) {
					String[] timeResult = result[0].split(" ");
					Logger.getRootLogger().info("timeResult result: " + JSON.toJSONString(timeResult));
					if(timeResult != null ){
						if (timeResult.length >= 4 && timeResult[4].split(":").length > 1) {
							hour = timeResult[4].split(":")[0].trim();
							Logger.getRootLogger().info("hour result:=========================== " + timeResult[4].split(":")[0].trim());
							min = timeResult[4].split(":")[1];
							Logger.getRootLogger().info("min result:=========================== " + timeResult[4].split(":")[1]);
						} else {
							min = timeResult[3].split(":")[0].trim();
						}
					}
				}
			}
		} catch (Exception e) {
			Logger.getRootLogger().error("时间获取失败：" + e);
		}
		runTime = day + "天" + hour + "小时" + min + "分";
		runTime = runTime.trim();
		Map<String, String> runTimeInfo = new HashMap<String, String>();
		runTimeInfo.put("runTimeInfo", runTime);
		Program cprogram = new Program();
		cprogram.setCpname("runTimeInfo");
		cprogram.setIp(MCAgentConfig.getInstance().getMonitoredPointIp());
		cprogram.setType(ProgramType.INFO);
		cprogram.setHeaders(runTimeInfo);
		return cprogram;
	}
}
